#!/bin/sh /etc/rc.common

START=98

start_service() {
	local basic_list="enable log_path tcp_stun_server udp_stun_server keep_alive_url local_ip"
	local port_list="enable_port id remarks port enable_forward \
		forward_mode external_port port_type delay log_level \
		internal_ip internal_port hook"
	for i in $basic_list
	do
		local eval $i="$(uci_get_by_type base 0 $i)"
	done ; unset i
	if [ "$enable" == 1 ]
	then
		include_file=/var/etc/natter.include
		echo "
#!/bin/sh
iptables -N natter 2> /dev/null
iptables -I INPUT -j natter 2> /dev/null
" \
		> $include_file			
		mkdir -p ${log_path}
		iptables_remove_rule
		mkdir -p /var/etc/natter
		for u in $(seq 0 $(($(uci show natter 2> /dev/null | egrep '@ports\[[0-9]\]+=ports' | wc -l) - 1)))
		do
			for i in $port_list
			do
				local eval $i="$(uci_get_by_type ports $u $i)"
				echo "$i : $(uci_get_by_type ports $u $i)"
			done ; unset i

			[ "$enable_port" != 1 ] && continue

			case $port_type in
			tcp | udp)
				eval external_${port_type}="$local_ip:$external_port"
				eval internal_${port_type}="$internal_ip:$internal_port"
				iptables_type=$port_type
			;;
			both)
				external_tcp="$local_ip:$external_port"
				external_udp="$local_ip:$external_port"
				internal_tcp="$internal_ip:$internal_port"
				internal_udp="$internal_ip:$internal_port"
				iptables_type="tcp udp"
			;;
			esac
			
			log_file=${log_path}/natter-${id}-${remarks}.log
			json_file=/var/etc/natter/natter-${id}-${remarks}.json
			status_file=${log_path}/natter-${id}-${remarks}.json

			echo "{
	\"logging\": {
		\"level\": \"$log_level\",
		\"log_file\": \"${log_file}\"
	},
	\"status_report\": {
		\"hook\": \"$hook\",
		\"status_file\": \"${status_file}\"
	},
	$(
	case ${forward_mode} in
	1)
		echo "
	\"open_port\": {
		\"tcp\": [

		],
		\"udp\": [

		]
	},"
		echo "
	\"forward_port\": {
		\"tcp\": [
			$([ "$internal_tcp" ] && echo \"${internal_tcp}\")
		],
		\"udp\": [
			$([ "$internal_udp" ] && echo \"${internal_udp}\")
		]
	},"
	;;
	2)
		echo "
	\"open_port\": {
		\"tcp\": [
			$([ "$external_tcp" ] && echo \"${external_tcp}\")
		],
		\"udp\": [
			$([ "$external_udp" ] && echo \"${external_udp}\")
		]
	},"
		echo "
	\"forward_port\": {
		\"tcp\": [

		],
		\"udp\": [

		]
	},"
	;;
	esac
	)
	\"stun_server\": {
		\"tcp\": $(
	printf "["
	j=1 ; for i in $tcp_stun_server
	do
		[[ "$j" == 1 ]] && unset j || printf ", "
		printf '"%s"' $i
	done ; unset i j
	printf "],")
		\"udp\": $(
	printf "["
	j=1 ; for i in $udp_stun_server
	do
		[[ "$j" == 1 ]] && unset j || printf ", "
		printf '"%s"' $i
	done ; unset i j
	printf "]")
	},
	\"keep_alive\": \"$keep_alive_url\"
}" \
			> $json_file
			echo "json File: $json_file"
			echo "log File: $log_file"
			echo "status File: $status_file"
			sleep $delay
			for i in $(ps -efww | egrep 'natter.py' | grep -v grep | grep -v $$ | grep "$id" | awk '{print $1}')
			do
				kill -9 "$i" 2> /dev/null
			done
			$(command -v python) /usr/share/natter/natter.py -c $json_file &
			if [ "$enable_forward" == 1 ]
			then
				case $forward_mode in
				1)
					:
				;;
				2)
					iptables -N natter 2> /dev/null
					iptables -I INPUT -j natter 2> /dev/null
					for i in $iptables_type
					do
						# iptables -A natter \
						#	-p $i -m $i --dport $external_port \
						#	-m comment --comment "nt-op-$id-$remarks" \
						#	-j ACCEPT
						# echo "iptables -A natter -p $i -m $i --dport $external_port -m comment --comment \"nt-op-$id-$remarks\" -j ACCEPT" >> ${include_file}
						iptables -t nat -A PREROUTING \
							-p $i -m $i --dport $external_port \
							-m comment --comment "nt-dnat-$id-$remarks" \
							-j DNAT \
							--to-destination $internal_ip:$internal_port
						echo "iptables -t nat -A PREROUTING -p $i -m $i --dport $external_port -m comment --comment \"nt-dnat-$id-$remarks\" -j DNAT --to-destination $internal_ip:$internal_port" >> ${include_file}
					done ; unset i
				;;
				esac
				uci set natter.@ports[$u].external_port_tcp="WAIT"
				uci set natter.@ports[$u].external_port_udp="WAIT"
				uci commit natter
				{
					sleep 10
					external_port_tcp=$(grep "[INFO]" $log_file 2> /dev/null | grep TCP | egrep -o "[0-9]+" | awk 'END{print}')
					external_port_udp=$(grep "[INFO]" $log_file 2> /dev/null | grep UDP | egrep -o "[0-9]+" | awk 'END{print}')
					[ "${external_port_tcp}" ] || external_port_tcp="none"
					[ "${external_port_udp}" ] || external_port_udp="none"
					uci set natter.@ports[$u].external_port_tcp="$external_port_tcp"
					uci set natter.@ports[$u].external_port_udp="$external_port_udp"
					uci commit natter
				} &
			fi
			for i in $port_list
			do
				unset $(echo $i)
			done ; unset i
			unset iptables_type internal_tcp internal_udp external_tcp external_udp external_port_tcp external_port_udp
		done ; unset u
	else
		echo "Natter is disabled ..."
		stop_service
	fi
}

stop_service() {
	echo "Stopping Natter ..."
	for i in $(ps -efww | egrep 'natter.py' | grep -v grep | grep -v $$ | awk '{print $1}')
	do
		kill -9 "$i" 2> /dev/null
	done
	iptables_remove_rule
	rm /var/etc/natter.include 2> /dev/null
	rm -r /var/etc/natter 2> /dev/null
	rm -r /tmp/natter 2> /dev/null
}

iptables_remove_rule() {
	echo "Removing iptable rules ..."
	iptables -D INPUT -j natter 2> /dev/null
	iptables -F natter 2> /dev/null
	iptables -X natter 2> /dev/null
	iptables-save | grep -v 'nt-dnat' | iptables-restore
}

stop() {
	stop_service
}

start() {
	start_service
}

restart() {
	stop
	start
}

service_triggers() {
	procd_add_reload_trigger "natter"
}

uci_get_by_type() {
	local ret=$(uci get natter.@$1[$2].$3 2>/dev/null)
	echo ${ret:=$4}
}
